package cn.tedu.user.management.service.impl;

import cn.tedu.rtms.commons.ex.ServiceException;
import cn.tedu.rtms.commons.pojo.po.UserLoginInfoPO;
import cn.tedu.rtms.commons.pojo.vo.PageData;
import cn.tedu.rtms.commons.web.ServiceCode;
import cn.tedu.user.management.dao.cache.repository.IUserJwtRepository;
import cn.tedu.user.management.dao.persist.repository.*;
import cn.tedu.user.management.pojo.dto.UserLoginInfoDTO;
import cn.tedu.user.management.pojo.entity.User;
import cn.tedu.user.management.pojo.entity.UserRole;
import cn.tedu.user.management.pojo.param.UserAddNewParam;
import cn.tedu.user.management.pojo.param.UserLoginInfoParam;
import cn.tedu.user.management.pojo.param.UserPasswordParam;
import cn.tedu.user.management.pojo.param.UserUpdateInfoParam;
import cn.tedu.user.management.pojo.vo.*;
import cn.tedu.user.management.security.UserDetails;
import cn.tedu.user.management.service.IUserService;
import com.alibaba.fastjson.JSON;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 处理员工数据的业务实现类
 *
 * @author java@tedu.cn
 * @version 0.0.1
 */
@Slf4j
@Service
public class UserServiceImpl implements IUserService {

    @Value("${csmall.crud.default-query-page-size}")
    private Integer defaultQueryPageSize;
    @Value("${csmall.jwt.secret-key}")
    private String secretKey;
    @Value("${csmall.jwt.duration-in-minute}")
    private Long durationInMinute;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private IUserRepository userRepository;
    @Autowired
    private ISectionJobRepository sectionJobRepository;
    @Autowired
    private IRentRepository rentRepository;
    @Autowired
    private IMaintainRepository maintainRepository;
    @Autowired
    private IUserRoleRepository userRoleRepository;
    @Autowired
    private IUserJwtRepository userCacheRepository;
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private ISectionRepository sectionRepository;

    public UserServiceImpl() {
        log.debug("创建业务类对象：UserServiceImpl");
    }

    @Override
    public UserLoginInfoDTO login(UserLoginInfoParam userLoginInfoParam, String remoteAddr, String userAgent) {
        log.debug("开始处理【员工登录】的业务，参数：{}", userLoginInfoParam);
        Authentication authentication = new UsernamePasswordAuthenticationToken(
                userLoginInfoParam.getUsername(), userLoginInfoParam.getPassword());
        Authentication authenticateResult
                = authenticationManager.authenticate(authentication);
        log.debug("认证通过！（如果未通过，过程中将抛出异常，你不会看到此条日志！）");
        log.debug("认证结果：{}", authenticateResult);
        log.debug("认证结果中的当事人：{}", authenticateResult.getPrincipal());
        UserDetails userDetails = (UserDetails) authenticateResult.getPrincipal();

        // 使用JWT机制时，登录成功后不再需要将认证信息存入到SecurityContext
        // SecurityContext securityContext = SecurityContextHolder.getContext();
        // securityContext.setAuthentication(authenticateResult);

        // 需要存入到JWT中的数据
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", userDetails.getId());
        claims.put("username", userDetails.getUsername());
        String authorityListJsonString = JSON.toJSONString(userDetails.getAuthorities());
        // claims.put("authoritiesJsonString", authorityListJsonString);

        // 生成JWT，以下代码是相对固定的
        long tokenDuration = durationInMinute * 60 * 1000;
        Date tokenExpiration = new Date(System.currentTimeMillis() + tokenDuration);
        String jwt = Jwts.builder()
                // Header：声明算法与Token类型
                .setHeaderParam("alg", "HS256")
                .setHeaderParam("typ", "JWT")
                // Payload：数据，具体表现为Claims
                .setClaims(claims)
                .setExpiration(tokenExpiration)
                // Verify Signature：验证签名
                .signWith(SignatureAlgorithm.HS256, secretKey)
                .compact();
        log.debug("生成了JWT数据：{}", jwt);

        // 需要缓存到Redis中的数据
        UserLoginInfoPO userLoginInfoPO = new UserLoginInfoPO();
        userLoginInfoPO.setId(userDetails.getId());
        userLoginInfoPO.setEnable(userDetails.isEnabled() ? 1 : 0);
        userLoginInfoPO.setRemoteAddr(remoteAddr);
        userLoginInfoPO.setUserAgent(userAgent);
        userLoginInfoPO.setAuthorityListJsonString(authorityListJsonString);
        userCacheRepository.saveLoginInfo(jwt, userLoginInfoPO, tokenDuration);
        log.debug("向Redis中写入此员工的登录信息：{}", userLoginInfoPO);

        // 准备返回
        return new UserLoginInfoDTO()
                .setId(userDetails.getId())
                .setUsername(userDetails.getUsername())
                .setAvatar(userDetails.getAvatar())
                .setToken(jwt)
                .setTokenExpiration(tokenExpiration);
    }

    @Override
    public void logout(String jwt) {
        log.debug("开始处理【员工退出登录】的请求，参数：{}", jwt);
        userCacheRepository.delete(jwt);
    }

    @Override
    public void addNew(UserAddNewParam userAddNewParam, Integer enable) {
        log.debug("开始处理【注册账号】的业务，参数：{}", userAddNewParam);

        // 检查用户名是否被占用
        {
            // 从参数对象中获取员工的用户名
            String username = userAddNewParam.getUsername();
            // 调用Mapper对象的countByUsername()执行统计
            int count = userRepository.countByUsername(username);
            // 判断统计结果是否大于0
            if (count > 0) {
                // 是：抛出异常
                String message = "操作失败，用户名已经被占用！";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
            }
        }

        // 检查手机号码是否被占用
        {
            String phone = userAddNewParam.getPhone();
            int count = userRepository.countByPhone(phone);
            if (count > 0) {
                String message = "操作失败，手机号码已经被占用！";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
            }
        }

        // 检查电子邮箱是否被占用
        {
            String email = userAddNewParam.getEmail();
            int count = userRepository.countByEmail(email);
            if (count > 0) {
                String message = "操作失败，电子邮箱已经被占用！";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
            }
        }

        // 创建User对象
        User user = new User();
        // 复制属性
        BeanUtils.copyProperties(userAddNewParam, user);
        //设置权限
        user.setEnable(enable);
        //设置头像
        user.setAvatar("https://img1.baidu.com/it/u=172033757,2398290767&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500");
        //获取部门id
        Long sectionId = userAddNewParam.getSectionId()[userAddNewParam.getSectionId().length - 1];
        log.debug("sectionId:{}", sectionId);
        if (sectionId == 0) {
            String message = "操作失败，请选择部门！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }
        //获取职位id
        Long jobId = userAddNewParam.getJobId()[userAddNewParam.getJobId().length - 1];
        log.debug("jobId:{}", jobId);
        if (jobId == 0) {
            String message = "操作失败，请选择职位！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }

        //根据SectionId和JobId和jobId获取sectionJobId
        Long sectionJobId = sectionJobRepository.selectSectionJobId(sectionId, jobId);
        //补全User对象的属性值sectionJobId
        log.debug("sectionJobId：{}", sectionJobId);
        user.setSectionJobId(sectionJobId);
        // 补全User对象的属性值：lastLoginIP(null) / loginCount(0) / gmtLastLogin(null) / gmtCreate / gmtModified
        LocalDateTime now = LocalDateTime.now();
        user.setGmtCreate(now);
        user.setGmtModified(now);
        user.setLoginCount(0);
        // 从User对象中取出原密码，执行加密，再将密文存入到User对象中
        String rawPassword = user.getPassword();
        String encodedPassword = passwordEncoder.encode(rawPassword);
        user.setPassword(encodedPassword);
        // 调用Mapper对象的insert()执行插入
        int rows = userRepository.insert(user);
        if (rows != 1) {
            String message = "操作失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_INSERT, message);
        }

        // 为新添加的员工分配角色
        UserRole userRole = new UserRole();
        //获取新增用户id
        userRole.setUserId(user.getId());
        //设置默认角色4
        userRole.setRoleId(4L);
        //设置创建时间
        userRole.setGmtCreate(now);
        // 调用Mapper对象的insert()执行插入
        rows = userRoleRepository.insert(userRole);
        if (rows != 1) {
            String message = "操作失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_INSERT, message);
        }

    }

    @Override
    public void delete(Long id, Long currentId) {
        log.debug("开始处理【根据id删除员工】的业务，id：{}, currentId:{}", id, currentId);
        //判断当前账号权值与目标对象权值
        Integer weight = userRepository.getWeightById(id);
        Integer currentWeight = userRepository.getWeightById(currentId);
        if (currentWeight == null) {
            String message = "操作失败，您的权限不足！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_FORBIDDEN, message);
        }
        if (weight == null || currentWeight > weight) {
            deleteById(id);
            return;
        }
        String message = "操作失败，您的权限不足！";
        log.warn(message);
        throw new ServiceException(ServiceCode.ERROR_FORBIDDEN, message);
    }

    private void deleteById(Long id) {
        log.debug("开始处理【根据id删除员工】的业务，id：{}", id);
        // 检查尝试删除的数据是否存在
        Object queryResult = userRepository.getStandardById(id);
        if (queryResult == null) {
            String message = "删除员工失败，尝试访问的数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }

        //判断员工是否是部门负责人，若是则无法删除
        log.debug("开始处理【判断是否是部门负责人】的业务，参数：{}", id);
        int count = sectionRepository.countByUserId(id);
        if (count > 0) {
            String message = "删除员工失败，该员工为部门负责人！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_DELETE, message);
        }

        //判断是否有工具未归还
        log.debug("开始处理【判断是否有工具未归还】的业务，参数：{}", id);
        count = userRepository.countRentNoReturnById(id);
        log.debug("count:{}", count);
        if(count>0){
            String message = "删除员工失败，该员工尚有工具未归还！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_DELETE, message);
        }

        // 执行删除--员工表
        log.debug("即将执行删除数据，参数：{}", id);
        int rows = userRepository.deleteById(id);
        if (rows != 1) {
            String message = "删除员工失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_DELETE, message);
        }


        //查询是否有角色关联
        count = userRoleRepository.countByUserId(id);
        if(count>0) {
            // 执行删除--员工与角色的关联表
            log.debug("即将执行删除数据，参数：{}", id);
            rows = userRoleRepository.deleteByUserId(id);
            if (rows != count) {
                String message = "删除员工失败，服务器忙，请稍后再尝试！";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERROR_DELETE, message);
            }
        }


        //查询是否有借用记录
        count = rentRepository.countByUserId(id);
        if(count>0) {
            // 执行删除--借用记录
            log.debug("即将执行删除数据，参数：{}", id);
            rows = rentRepository.deleteByUserId(id);
            if (rows != count) {
                String message = "删除员工失败，服务器忙，请稍后再尝试！";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERROR_DELETE, message);
            }
        }


        //查询是否有维修记录
        count = maintainRepository.countByUserId(id);
        if(count>0) {
            // 执行删除--维修记录
            log.debug("即将执行删除数据，参数：{}", id);
            rows = maintainRepository.deleteByUserId(id);
            if (rows != count) {
                String message = "删除员工失败，服务器忙，请稍后再尝试！";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERROR_DELETE, message);
            }
        }

    }

    @Override
    public void resetPassword(Long id, Long currentId) {
        log.debug("开始处理【根据id重置密码】的业务，id：{}, currentId：{}", id, currentId);
        //判断当前账号权值与目标对象权值
        Integer weight = userRepository.getWeightById(id);
        Integer currentWeight = userRepository.getWeightById(currentId);
        if (currentWeight== null) {
            String message = "操作失败，您的权限不足！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_FORBIDDEN, message);
        }
        if (weight == null || currentWeight > weight) {
            //设置默认密码
            String defaultPassword = "123456";
            //创建User对象
            User user = new User();
            user.setId(id);
            //加密
            String encodedPassword = passwordEncoder.encode(defaultPassword);
            user.setPassword(encodedPassword);
            // 调用Mapper对象的update()方法执行修改
            int rows = userRepository.update(user);
            if (rows != 1) {
                String message = "重置密码失败！";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERROR_UPDATE, message);
            }
            return;
        }

        String message = "操作失败，您的权限不足！";
        log.warn(message);
        throw new ServiceException(ServiceCode.ERROR_FORBIDDEN, message);

    }

    @Override
    public void setEnable(Long id) {
        updateEnableById(id, 1);
    }

    @Override
    public void setEnableAll() {
        List<UserListItemVO> regLists = userRepository.regList();
        for (UserListItemVO regList : regLists) {
            updateEnableById(regList.getId(), 1);
        }
    }

    @Override
    public void setDisable(Long id, Long currentId) {
        //判断当前账号权值与目标对象权值
        Integer weight = userRepository.getWeightById(id);
        Integer currentWeight = userRepository.getWeightById(currentId);
        if (currentWeight == null) {
            String message = "操作失败，您的权限不足！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_FORBIDDEN, message);
        }
        if (weight == null || currentWeight > weight) {
            updateEnableById(id, 0);
            return;
        }
        String message = "操作失败，您的权限不足！";
        log.warn(message);
        throw new ServiceException(ServiceCode.ERROR_FORBIDDEN, message);
    }

    @Override
    public PageData<UserListItemVO> list(Integer pageNum) {
        log.debug("开始处理【查询员工列表】的业务，页码：{}", pageNum);
        PageData<UserListItemVO> pageData = userRepository.list(pageNum, defaultQueryPageSize);
        return pageData;
    }

    @Override
    public PageData<UserListItemVO> regList(Integer pageNum) {
        log.debug("开始处理【查询注册列表】的业务，页码：{}", pageNum);
        PageData<UserListItemVO> pageData = userRepository.regList(pageNum, defaultQueryPageSize);
        return pageData;
    }

    @Override
    public PageData<UserListItemVO> list(Integer pageNum, Integer pageSize) {
        log.debug("开始处理【查询员工列表】的业务，页码：{}，每页记录数：{}", pageNum, pageSize);
        PageData<UserListItemVO> pageData = userRepository.list(pageNum, pageSize);
        return pageData;
    }

    @Override
    public PageData<UserListItemVO> regList(Integer pageNum, Integer pageSize) {
        log.debug("开始处理【查询注册列表】的业务，页码：{}，每页记录数：{}", pageNum, pageSize);
        PageData<UserListItemVO> pageData = userRepository.regList(pageNum, pageSize);
        return pageData;
    }

    @Override
    public List<UserListItemVO> selectByKeywords(String Keywords) {
        log.debug("开始处理【根据关键字查询员工】的业务，关键字：{}", Keywords);
        List<UserListItemVO> list = userRepository.selectByKeywords(Keywords);
        return list;
    }

    private void updateEnableById(Long id, Integer enable) {
        log.debug("开始处理【{}员工】的业务，ID：{}，目标状态：{}", ENABLE_TEXT[enable], id, enable);
        // 检查数据是否存在
        UserStandardVO queryResult = userRepository.getStandardById(id);
        if (queryResult == null) {
            String message = ENABLE_TEXT[enable] + "员工失败，尝试访问的数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }

        // 检查当前状态是否与参数表示的状态相同
        if (queryResult.getEnable().equals(enable)) {
            String message = ENABLE_TEXT[enable] + "员工失败，当前员工已经处于"
                    + ENABLE_TEXT[enable] + "状态！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }

        // 准备执行更新
        User user = new User();
        user.setId(id);
        user.setEnable(enable);
        log.debug("即将修改数据，参数：{}", user);
        int rows = userRepository.updateById(user);
        if (rows != 1) {
            String message = ENABLE_TEXT[enable] + "员工失败，服务器忙，请稍后再次尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_UPDATE, message);
        }
    }

    @Override
    public void updateInfoById(Long id, UserUpdateInfoParam userUpdateInfoParam, Long currentId) {
        log.debug("开始处理【修改资料】的业务，ID：{}，新数据：{}, 当前账号id:{}", id, userUpdateInfoParam, currentId);
        //判断是否是修改个人资料
        if(currentId == 0) {
            updateInfoById(id,userUpdateInfoParam);
            return ;
        }

        //判断当前账号权值与目标对象权值
        Integer weight = userRepository.getWeightById(id);
        Integer currentWeight = userRepository.getWeightById(currentId);
        if (currentWeight == null) {
            String message = "操作失败，您的权限不足！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_FORBIDDEN, message);
        }
        if (weight == null || currentWeight > weight || currentWeight == 99) {
            updateInfoById(id,userUpdateInfoParam);
            return;
        }
        String message = "操作失败，您的权限不足！";
        log.warn(message);
        throw new ServiceException(ServiceCode.ERROR_FORBIDDEN, message);

    }

    private void updateInfoById(Long id, UserUpdateInfoParam userUpdateInfoParam) {
        log.debug("开始处理【修改资料】的业务，ID：{}，新数据：{}", id, userUpdateInfoParam);
        // 调用Mapper对象的getStandardById()执行查询
        UserStandardVO queryResult = userRepository.getStandardById(id);
        // 判断查询结果是否为null
        if (queryResult == null) {
            // 是：抛出异常
            String message = "修改信息失败，尝试修改的员工数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }

        // 调用Mapper对象的countByNameAndNotId()执行统计
        int count = userRepository.countByUsernameAndNotId(id, userUpdateInfoParam.getUsername());
        // 判断统计结果是否大于0
        if (count > 0) {
            // 是：名称被占用，抛出异常
            String message = "修改信息失败，该用户名已经被占用！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }

        //判断手机号是否重复
        count = userRepository.countByPhoneAndNotId(id, userUpdateInfoParam.getPhone());
        // 判断统计结果是否大于0
        if (count > 0) {
            // 是：名称被占用，抛出异常
            String message = "修改信息失败，该手机号已经被占用！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }

        //判断邮箱是否重复
        count = userRepository.countByEmailAndNotId(id, userUpdateInfoParam.getEmail());
        // 判断统计结果是否大于0
        if (count > 0) {
            // 是：名称被占用，抛出异常
            String message = "修改信息失败，该电子邮箱已经被占用！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }
        //未防止空指针，先将部门职位二者其中一个为空的情况先抛异常
        if ((userUpdateInfoParam.getSectionId() == null && userUpdateInfoParam.getJobId() != null)
                || (userUpdateInfoParam.getSectionId() != null && userUpdateInfoParam.getJobId() == null)) {
            log.debug("部门职位选择未同步,其中一个为空!");
            String message = "修改数据失败，部门职位必须同时选择(或者同时不选)，不能只选一个!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_UPDATE, message);
        }

        //未传递部门职位信息
        if ((userUpdateInfoParam.getSectionId() == null && userUpdateInfoParam.getJobId() == null)
                || (userUpdateInfoParam.getSectionId()[userUpdateInfoParam.getSectionId().length - 1] == 0 &&
                userUpdateInfoParam.getJobId()[userUpdateInfoParam.getJobId().length - 1] == 0)) {
            log.debug("未传递部门职位信息，直接操作");
            // 创建User对象
            User user = new User();
            // 复制属性，设置ID
            BeanUtils.copyProperties(userUpdateInfoParam, user);
            user.setId(id);
            // 调用Mapper对象的update()方法执行修改
            int rows = userRepository.update(user);
            if (rows != 1) {
                String message = "修改数据失败，服务器忙，请稍后再尝试！";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERROR_UPDATE, message);
            }
            return;
        }

        //只选择部分部门职位
        if ((userUpdateInfoParam.getSectionId()[userUpdateInfoParam.getSectionId().length - 1] == 0 &&
                userUpdateInfoParam.getJobId()[userUpdateInfoParam.getJobId().length - 1] != 0)
                || (userUpdateInfoParam.getSectionId()[userUpdateInfoParam.getSectionId().length - 1] != 0 &&
                userUpdateInfoParam.getJobId()[userUpdateInfoParam.getJobId().length - 1] == 0)) {
            log.debug("部门职位选择未同步!");
            String message = "修改数据失败，部门职位必须同时选择(或者同时不选)，不能只选一个!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_UPDATE, message);
        }

        //获取部门职位id
        Long sectionId = userUpdateInfoParam.getSectionId()[userUpdateInfoParam.getSectionId().length - 1];
        Long jobId = userUpdateInfoParam.getJobId()[userUpdateInfoParam.getJobId().length - 1];
        log.debug("开始处理传递了【部门职位】的处理!sectionId:{},jobId:{}", sectionId, jobId);
        //查看部门职位表的关联数量
        count = sectionJobRepository.countBySectionIdAndJobId(sectionId, jobId);
        // 判断统计结果是否大于0
        if (count != 1) {
            // 暂无数据
            String message = "修改员工信息失败，该部门暂未提供此岗位哦，建议您刷新一下职位列表！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }
        //获取部门职位id值
        Long sectionJobId = sectionJobRepository.selectSectionJobId(sectionId, jobId);
        // 创建User对象
        User user = new User();
        // 复制属性，设置ID
        BeanUtils.copyProperties(userUpdateInfoParam, user);
        user.setId(id);
        user.setSectionJobId(sectionJobId);
        // 调用Mapper对象的update()方法执行修改
        int rows = userRepository.update(user);
        if (rows != 1) {
            String message = "修改员工信息失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_UPDATE, message);
        }
    }

    @Override
    public UserStandardVO getStandardById(Long id) {
        log.debug("开始处理【根据ID查询员工信息】的业务，参数：{}", id);
        UserStandardVO queryResult = userRepository.getStandardById(id);
        if (queryResult == null) {
            // 是：抛出异常
            String message = "查询员工信息失败，员工数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }
        return queryResult;
    }

    @Override
    public void updatePassword(Long id, UserPasswordParam userPasswordParam) {
        log.debug("开始处理【修改密码】的业务，参数：{}", userPasswordParam);
        String rawPassword = userPasswordParam.getRawPassword();
        String newPassword = userPasswordParam.getNewPassword();
        String verifyPassword = userPasswordParam.getVerifyPassword();
        if (rawPassword == null || newPassword == null || verifyPassword == null) {
            //密码为空
            String message = "修改失败，密码不能为空！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_BAD_REQUEST, message);
        }
        if (rawPassword.length() < 4 || rawPassword.length() > 16 ||
                newPassword.length() < 4 || newPassword.length() > 16 ||
                verifyPassword.length() < 4 || verifyPassword.length() > 16
        ) {
            //密码太短或者太长
            String message = "修改失败，密码长度必须为4~16！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_BAD_REQUEST, message);
        }
        if (!newPassword.equals(verifyPassword)) {
            //两次输入的新密码不同
            String message = "修改失败，两次新密码不同！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }

        if (rawPassword.equals(newPassword)) {
            //新密码与旧密码相同
            String message = "修改失败，新旧密码相同！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }

        //创建User对象
        User user = new User();
        user.setId(id);
        //加密
        String encodedPassword = passwordEncoder.encode(newPassword);
        user.setPassword(encodedPassword);
        // 调用Mapper对象的update()方法执行修改
        int rows = userRepository.update(user);
        if (rows != 1) {
            String message = "修改密码失败！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_UPDATE, message);
        }

    }

    @Override
    public UserOwnInfoVO userOwnInfo(Long id) {
        log.debug("开始处理【查询当前账号资料】的业务，参数：{}", id);
        UserOwnInfoVO queryResult = userRepository.getUserOwnInfoById(id);
        if (queryResult == null) {
            // 是：抛出异常
            String message = "查询信息失败，当前账号数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }
        return queryResult;
    }

    @Override
    public UserRoleStandardVO getUserRoleById(Long id) {
        log.debug("开始处理【根据id查询角色信息】的业务，参数：{}", id);
        UserRoleStandardVO queryResult = userRepository.getUserRoleById(id);
        if (queryResult == null) {
            // 是：抛出异常
            String message = "查询员工角色失败，员工角色不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }
        return queryResult;
    }

    @Override
    public List<UserListVO> selectUserList() {
        log.debug("开始处理【查询员工列表】的业务");
        return userRepository.selectUserList();
    }

}
